﻿using System;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.ServiceModel.DomainServices.Client;
using System.ServiceModel.DomainServices.Client.ApplicationServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using RIABlog.Web.Models;

namespace RIABlog.Views
{
    public partial class BlogPosts : BlogPageBase, INotifyPropertyChanged
    {
		#region Public Members

		/// <summary>
		/// Доступно ли добавление/удаление постов
		/// </summary>
    	public Visibility AddRemovePostVisibility
    	{
    		get
    		{
				var blog = this.BlogContext.Blogs.FirstOrDefault(b => b.Id == this._currentBlogId);

				if
				(
					(blog != null)
					&&
					(blog.Author == WebContext.Current.User.Name)
				)
				{
					return Visibility.Visible;
				}
				else
				{
					return Visibility.Collapsed;
				}
			}
    	}

		/// <summary>
		/// Доступно ли добавление комментариев
		/// </summary>
		public Visibility AddCommentVisibility
		{
			get { return WebContext.Current.User.IsAuthenticated ? Visibility.Visible : Visibility.Collapsed; }
		}

        public BlogPosts()
        {
            InitializeComponent();
        }

		#endregion

		#region Private Members

		/// <summary>
		/// Идентификатор текущего блога
		/// </summary>
    	private Guid _currentBlogId;

		/// <summary>
		/// Новый экземпляр сущности BlogPost
		/// </summary>
    	private BlogPost _newPost;

        // Executes when the user navigates to this page.
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            // получаем идентификатор блога из QueryString
			this._currentBlogId = new Guid(this.NavigationContext.QueryString["BlogId"]);

            var currentBlog = this.BlogContext.Blogs.SingleOrDefault(b => b.Id == this._currentBlogId);

            if(currentBlog == null) // это чтобы не ломалось при рефреше в браузере
            {
                this.NavigateHome();
                return;
            }

            // задаем заголовок страницы
			this.HeaderText.Text = currentBlog.Title;

            // очищаем EntitySet от старых записей
            this.BlogContext.BlogPosts.Clear();

            // получаем с сервера записи текущего блога
			this.BlogContext.Load(this.BlogContext.GetBlogPostsQuery(this._currentBlogId));

			// создаем новый экземпляр сущности
			this._newPost = new BlogPost() { BlogId = this._currentBlogId };
        	this.formNewPost.CurrentItem = this._newPost;

			// добавляем проверку юзера в случае аутентификации
			WebContext.Current.Authentication.LoggedIn += this.AuthenticationEventHandler;
			WebContext.Current.Authentication.LoggedOut += this.AuthenticationEventHandler;
        }

		protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
		{
			base.OnNavigatingFrom(e);

			// здесь обязательно нужно отписываться
			WebContext.Current.Authentication.LoggedIn -= this.AuthenticationEventHandler;
			WebContext.Current.Authentication.LoggedOut -= this.AuthenticationEventHandler;
		}

        private void AuthenticationEventHandler(object sender, AuthenticationEventArgs evt)
        {
            this.RaisePropertyChanged(() => AddRemovePostVisibility);
            this.RaisePropertyChanged(() => AddCommentVisibility);

            this.accordionBlogPosts.SelectedIndex = -1;
        }

		private void formNewPost_EditEnded(object sender, DataFormEditEndedEventArgs e)
		{
			if(e.EditAction != DataFormEditAction.Commit)
			{
				return;
			}

			// добавляем запись и сразу запускаем сохранение
			this.BlogContext.BlogPosts.Add(this._newPost);

            this.BlogContext.SubmitChanges(this.AddingCompleted, null);
		}

		private void AddingCompleted(SubmitOperation op)
		{
			if(op.HasError)
			{
				// если произошла ошибка - отменяем изменения
				this.BlogContext.RejectChanges();
			}

			// создаем новый экземпляр сущности
			this._newPost = new BlogPost { BlogId = this._currentBlogId };
			this.formNewPost.CurrentItem = this._newPost;
		}

        private void RemoveButton_Click(object sender, RoutedEventArgs e)
        {
            if (MessageBox.Show(ApplicationStrings.RemoveQueryText, ApplicationStrings.QuestionText, MessageBoxButton.OKCancel) == MessageBoxResult.Cancel)
            {
                return;
            }

            var post = (BlogPost)(((Button) sender).DataContext);

            // удаляем запись и сразу запускаем сохранение
            this.BlogContext.BlogPosts.Remove(post);

            this.BlogContext.SubmitChanges(this.RemovingCompleted, null);
        }

        private void RemovingCompleted(SubmitOperation op)
        {
            if (op.HasError)
            {
                // если произошла ошибка - отменяем изменения
                this.BlogContext.RejectChanges();
            }
        }

		#endregion

		#region Implementation of INotifyPropertyChanged

		public event PropertyChangedEventHandler PropertyChanged;

		private void RaisePropertyChanged<T>(Expression<Func<T>> expression)
		{
			var handler = this.PropertyChanged;
			if(handler == null)
			{
				return;
			}

			var body = expression.Body as MemberExpression;

			if (body == null)
			{
				throw new ArgumentException("expression");
			}

			handler(this, new PropertyChangedEventArgs(body.Member.Name));
		}

    	#endregion
    }
}
